package com.example.datachange.test;

import com.example.datachange.model.MyAutowired;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class Demo2 {
    HashMap<String, Object> beans = new HashMap<>();
    HashMap<String, String> map = new HashMap<>();
    //根据实际情况获得类的标识，避免重复
    String className = "";

    {
        beans.put("java.lang.String", "注入的字符串");
        beans.put("java.util.Date", new Date());
    }

    public static void main(String[] args) throws Exception {
        new Demo2().run();
    }

    public void run() throws IllegalAccessException {
        Fu<String, Date> zi = new Fu<String, Date>() {
        };
        //分别获取父类实际类型和泛型类型信息
        Class<?> fuclass = zi.getClass().getSuperclass();
        Type futype = zi.getClass().getGenericSuperclass();

        TypeVariable<? extends Class<?>>[] typeParameters = fuclass.getTypeParameters();
        Type[] actualTypeArguments = ((ParameterizedType) futype).getActualTypeArguments();

        //把对应的类型写入map
        int len = typeParameters.length;
        for (int i = 0; i < len; i++) {
            map.put(className + "." + typeParameters[i].getName(), actualTypeArguments[i].getTypeName());
        }

        Field[] fields = fuclass.getDeclaredFields();
        for (Field field : fields) {
            Annotation[] annotations = field.getDeclaredAnnotations();
            for (Annotation annotation : annotations) {
                if (annotation.annotationType().equals(MyAutowired.class)) {
                    //代表注入的字段
                    String fieldType = className + "." + field.getGenericType().getTypeName();
                    field.setAccessible(true);
                    String actualType = map.get(fieldType);
                    System.out.println(actualType);
                    field.set(zi, beans.get(actualType));
                    break;
                }
            }
        }
        System.out.println(zi);

    }
}


class Fu<T, E> {

    @MyAutowired
    private T t;

    @MyAutowired
    private E e;

    private T t2;

    @Override
    public String toString() {
        return t.toString() + "," + e.toString();
    }
}